#    This file is part of OpenPolitik.
#
#    OpenPolitik is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    OpenPolitik is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with OpenPolitik.  If not, see <http://www.gnu.org/licenses/>.
from google.appengine.ext import db
from google.appengine.api import users

# Game states:
# 0 - in lobby, users can join
# 1 - negotiations phase
# 2 - retreating
# 3 - builds
# 4 - game over
#
PHASES = ["Lobby", "Negotiations/Orders", "Retreats", "Builds", "Game Over"]

class Game(db.Model):
	name = db.StringProperty(required=True)
	state = db.IntegerProperty(choices=set(range(0, 5)), default=0)
	users = db.ListProperty(users.User)
	created = db.DateTimeProperty(auto_now=True)
	admin = db.UserProperty(required=True)
	date = db.StringProperty()
	due_date = db.StringProperty()

	def find_by_name(name):
		res = Game.all().filter("name = ", name).fetch(1)
		if res == []:
			return None
		return res[0]
	find_by_name = staticmethod(find_by_name)

	def delete(self):
		# delete our UIGS, our messages and our pieces
		uigs = UserInGame.all().filter("game = ", self).fetch(7)
		for u in uigs:
			u.delete()

		pieces = Piece.all().filter("game = ", self).fetch(150)
		for p in pieces:
			p.delete()

		orders = Order.all().filter("game = ", self).fetch(10)
		for o in orders:
			o.delete()

		while True:
			messages = Message.all().filter("game = ", self).fetch(1000)

			if messages == []:
				break

			for m in messages:
				m.delete()

		db.Model.delete(self)

class Message(db.Model):
	to = db.UserProperty(required=True)
	sender = db.UserProperty(required=True)
	game = db.ReferenceProperty(Game)
	subject = db.StringProperty(default="<no subject>")
	content = db.TextProperty(default="")
	flags = db.IntegerProperty(default=0)
	created = db.DateTimeProperty(auto_now=True)
	orig = db.SelfReferenceProperty()

	def get_messages(user, game, page, mine_too = False):
		num_per_page = 10
		return Message.all().filter("to = ", user).filter("game = ", game).order("-created").fetch(num_per_page, (page - 1) * num_per_page)

		if mine_too == False:
			print len(to_me)
			return to_me

		from_me = Message.all().filter("sender = ", user).filter("game = ", game).order("-created").fetch(num_per_page, (page - 1) * num_per_page)
		# merge the two
		res = []
		for i in range(0, 10):
			if to_me == [] and from_me == []:
				break
			
			if to_me == []:
				res.append(from_me.pop(0))
			elif from_me == [] or to_me[0].created > from_me[0].created:
				res.append(to_me.pop(0))
			else:
				res.append(from_me.pop(0))
		return res
			
	get_messages = staticmethod(get_messages)

class Order(db.Model):
	user = db.UserProperty(required=True)
	game = db.ReferenceProperty(Game, required=True)
	orders = db.StringProperty()
	created = db.DateTimeProperty(auto_now=True)

# Nations: (Turkey, England, France, Germany, Russia, Austria, Italy)
NATIONS = ["Turkey", "England", "France", "Germany", "Russia", "Austria", "Italy", "N"]
NATIONS_SHORT = [t[0] for t in NATIONS]
class UserInGame(db.Model):
	user = db.UserProperty(required=True)
	game = db.ReferenceProperty(Game, required=True)
	nation = db.StringProperty(choices=set(NATIONS), default="")

	def get_games_for_user(user):
		uigs = UserInGame.all().filter("user = ", user).fetch(100)

		games = []
		for uig in uigs:
			games.append(uig.game)

		return games
	get_games_for_user = staticmethod(get_games_for_user)

class UserOptions(db.Model):
	user = db.UserProperty(required=True)
	prefs = db.IntegerProperty(default=3)
	email = db.StringProperty(default="")

	SEND_EMAIL_ON_MESSAGE    = 0x0001
	SEND_EMAIL_ON_GAME_START = 0x0002

	def get_prefs(user):
		prefs = UserOptions.all().filter("user = ", user).fetch(1)

		if prefs == []:
			email = user.email()
			prefs = UserOptions(user=user, email=email)
			prefs.put()
			return prefs
		
		if prefs[0].email == "":
			prefs[0].email = user.email()
			prefs[0].put()
	
		return prefs[0]
	get_prefs = staticmethod(get_prefs)


# piece types:
#   0 - no type
#   1 - supply center
#   2 - army
#   3 - fleet
PIECES = ["", "SC", "A", "F"]
class Piece(db.Model):
	game = db.ReferenceProperty(Game, required=True)
	x = db.IntegerProperty(default=0)
	y = db.IntegerProperty(default=0)
	loc = db.StringProperty()
	type = db.IntegerProperty(choices=set([0,1,2,3]), default=0)
	colour = db.IntegerProperty(choices=set(range(0,8)), default=7)

